package net.posick.ws.soap;

import java.io.Serializable;
import java.util.List;

import net.posick.ws.xml.Name;
import net.posick.ws.xml.Namespace;
import net.posick.ws.xml.XmlElement;

public class SOAPBody extends SOAPBase implements Serializable
{
    private static final long serialVersionUID = 201403271221L;
    
    
    public static final String ELEMENT_NAME = "Body";
    
    public static final Name FQN = new Name(new Namespace(PREFIX_SOAP_1_1, NAMESPACE_SOAP_1_1), ELEMENT_NAME);

    
    protected SOAPFault fault = null;
    
    
    public SOAPBody()
    {
        super(FQN);
    }
    
    
    public SOAPBody(XmlElement child)
    throws SOAPException
    {
        super(FQN);
        
        if (child.getSiblings().size() == 0)
        {
            addChild(child);
        } else
        {
            throw new SOAPException("Invalid WS-I Basic Profice 1.2 SOAP Body \"" + child.getName() + "\". " + ERROR_MESSAGE_R9981);
        }
    }
    
    
    public SOAPBody(SOAPFault fault)
    {
        super(FQN);
        this.fault = fault;
        addChild(fault);
    }
    
    
    public SOAPBody(Throwable t)
    {
        super(FQN);
        setFault(t);
    }
    
    
    @Override
    public XmlElement add(XmlElement newNode, int mode) 
    throws SOAPException
    {
        switch (mode)
        {
            case XmlElement.LASTCHILD:
            case XmlElement.CHILD:
                if (child != null)
                {
                    throw new SOAPException("Invalid WS-I Basic Profice 1.2 SOAP Envelope \"" + newNode.getName() + "\". " + ERROR_MESSAGE_R9981);
                }
                break;
            case XmlElement.LAST:
            case XmlElement.NEXT:
                throw new SOAPException("Invalid WS-I Basic Profice 1.2 SOAP Envelope \"" + newNode.getName() + "\". " + ERROR_MESSAGE_R1011);
            default:
                break;
        }
        
        return super.add(newNode, mode);
    }


    @Override
    public XmlElement addChild(XmlElement newNode)
    throws SOAPException
    {
            return add(newNode, XmlElement.LASTCHILD);
    }


    public void setFault(Throwable t)
    {
        this.fault = new SOAPFault(t);
        addChild(this.fault);
    }
    
    
    public SOAPFault getFault()
    {
        return fault;
    }
    
    
    public static SOAPBody toSOAPBody(XmlElement xml)
    throws SOAPException
    {
        SOAPBody body = new SOAPBody();
        
        Name name = xml.getName();
        
        if (FQN.equals(name))
        {
            body.setName(name);
            body.setNamespaces(xml.getNamespaces());
            
            List<XmlElement> elements = xml.getChildren();
            if (elements != null && elements.size() > 0)
            {
                for (XmlElement element : elements)
                {
                    name = xml.getName();
                    Namespace ns = name.getNamespace();
                    String prefix = ns.getPrefix();
                    String namespaceUri = ns.getUri();
                    if (prefix == null || prefix.length() == 0)
                    {
                        throw new SOAPException("Invalid WS-I Basic Profice 1.2 SOAP Body \"" + xml.getName() + "\". " + ERROR_MESSAGE_R1014);
                    } else if (namespaceUri == null || namespaceUri.length() == 0)
                    {
                        throw new SOAPException("Invalid WS-I Basic Profice 1.2 SOAP Body \"" + xml.getName() + "\", Namespace Uri not present. " + ERROR_MESSAGE_R1014);
                    } else
                    {
                        body.addChild(element);
                    }
                }
            } else
            {
                throw new SOAPException("Invalid WS-I Basic Profice 1.2 SOAP Body \"" + xml.getName() + "\". " + ERROR_MESSAGE_R9981);
            }
        } else
        {
            throw new SOAPException("Invalid WS-I Basic Profice 1.2 SOAP Body \"" + xml.getName() + "\".  Must be of type \"" + FQN + "\"");
        }
        
        return body;
    }
}
